package cn.spikego.advicelite.client.core.event.impl

import cn.spikego.advicelite.client.core.event.util.EventCaller
import cn.spikego.advicelite.client.core.event.util.EventInitializer
import cn.spikego.advicelite.client.eventapi.events.callables.EventCancellable
import cn.spikego.advicelite.client.mapping.MappingManager
import net.bytebuddy.ByteBuddy
import net.bytebuddy.asm.Advice
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy
import net.bytebuddy.dynamic.scaffold.TypeValidation
import net.bytebuddy.implementation.bind.annotation.RuntimeType

import net.bytebuddy.matcher.ElementMatchers.named

class PlayerChatEvent() : EventCancellable(), EventInitializer {

    private var message: String? = null

    constructor(message: String) : this() {
        this.message = message
    }

    fun getMessage(): String? = message

    companion object {
        @JvmStatic
        @RuntimeType
        @Advice.OnMethodEnter(skipOn = Boolean::class)
        fun chat(@RuntimeType p_108740_: String): Boolean? {
        return if (EventCaller.callEvent("onChat", p_108740_)) true else null
        }
    }

    @Throws(Exception::class)
    override fun initialize(byteBuddy: ByteBuddy, loader: ClassLoader, mappingManager: MappingManager) {
        val clazz = loader.loadClass(mappingManager.translateClassName("net.minecraft.client.player.LocalPlayer"))
        val method = mappingManager.translateMethodName("net.minecraft.client.player.LocalPlayer", "chat(Ljava/lang/String;)V")
        byteBuddy.with(TypeValidation.DISABLED)
                .redefine(clazz)
                .visit(
                        Advice.to(Class.forName("me.dickmeister.client.core.event.impl.PlayerChatEvent"))
                                .withExceptionPrinting()
                                .on(named(method))
                )
                .make().load(loader, ClassReloadingStrategy.fromInstalledAgent())
    }
}